package com.eugenema.service;

import com.alibaba.fastjson.JSON;
import com.eugenema.entity.UpdateInfo;
import com.eugenema.util.ConfigUtil;
import com.eugenema.util.FileUtil;
import com.eugenema.windowGui.component.PopupJFrame;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;

/**
 * <p>标题：升级服务</p>
 * <p>
 * 功能：
 * </p>
 * <p>其他说明：</p>
 * <p>作者：马寅广</p>
 * <p>审核：</p>
 * <p>重构：</p>
 * <p>创建日期：2023/10/25 8:54</p>
 */
public class UpdateService {
    /** 日志 */
    private static Logger logger = LoggerFactory.getLogger(UpdateService.class);
    /** 更新信息地址 key */
    private static final String UPDATE_INFO_KEY = "updateInfoAdd";
    /** 本地更新标志文件 */
    public static final String UPDATE_FLAG_FILE = "updateFlag.txt";
    /** 程序当前版本信息，默认基础版本信息 */
    public static UpdateInfo nowVersionInfo = UpdateInfo.baseUpdatInfo();
    /** 更新程序 */
    private static final String UPDATE_PROGRAM = System.getProperty("user.dir") + File.separator + "update.exe";
    /** 更新程序文件名 */
    public static final String UPDATE_FILE = "update.exe";

    /**
     * 检查升级
     *
     * @return 用户不升级或没有新版本，则返回 true。升级，则返回 false
     * @author 马寅广
     * @date 2023/10/25 8:54
     **/
    public static boolean updateCheck() {
        try {
            //获取远程更新日志
            logger.info("开始获取远程更新信息……");
            URL url = new URL(ConfigUtil.getProperty(UPDATE_INFO_KEY));
            HttpURLConnection con = (HttpURLConnection) url.openConnection();
            con.setRequestMethod("GET");
            //读取日志内容
            logger.info("获取更新信息成功，正在解析……");
            BufferedReader in = null;
            String updateJson = "";
            try {
                in = new BufferedReader(new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8));
                StringBuilder updateJsonSb = new StringBuilder();
                String line;
                while ((line = in.readLine()) != null) {
                    updateJsonSb.append(line);
                }
                in.close();
                updateJson = updateJsonSb.toString();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            logger.debug("接收到更新信息：{}", updateJson);
            UpdateInfo updateInfo = JSON.parseObject(updateJson, UpdateInfo.class);
            //检查本地是否有更新标志文件
            if (FileUtil.exist(UPDATE_FLAG_FILE)) {
                //有，则比较版本号
                nowVersionInfo = JSON.parseObject(FileUtil.read(UPDATE_FLAG_FILE), UpdateInfo.class);
                if (checkVersion(updateInfo)) {
                    //本地版本号大于等于远程版本号，则不升级
                    return true;
                }
            } else {
                // 创建本地更新标志文件，写入基础版本信息
                if (FileUtil.createFile(UPDATE_FLAG_FILE)) {
                    FileUtil.write(UPDATE_FLAG_FILE, nowVersionInfo.toString());
                }
            }
            // 有新版本，弹出升级提示框
            logger.info("检测到新版本！");
            PopupJFrame jFrame = new PopupJFrame(updateInfo, nowVersionInfo);
            jFrame.showJFrame();
            // 持续检查弹窗是否已点击
            while (PopupJFrame.isOk == null) {
                Thread.sleep(300);
            }
            if (!PopupJFrame.isOk) {
                logger.info("用户取消升级！");
            }
            return !PopupJFrame.isOk;
        } catch (Exception e) {
            logger.error("获取更新信息失败：", e);
            return true;
        }
    }

    /**
     * 检查版本是否需要升级
     * </br>主程序或更新程序的远程版本是否小于本地版本
     *
     * @author Eugenema
     * @date 2023/12/7 21:21
     *
     * @param updateInfo 获取到的更新信息
     *
     * @return true 为不升级
     **/
    private static boolean checkVersion(UpdateInfo updateInfo) {
        boolean mainFlag = false;
        boolean updateFlag = false;
        if (mainFlag = updateInfo.getVersionMain().compareTo(nowVersionInfo.getVersionMain()) <= 0) {
            logger.info("主程序本地版本号【{}】大于等于远程版本号【{}】，不升级", new String[]{nowVersionInfo.getVersionMain(), updateInfo.getVersionMain()});
        }
        if (updateFlag = updateInfo.getVersionUpdate().compareTo(nowVersionInfo.getVersionUpdate()) <= 0) {
            logger.info("更新程序本地版本号【{}】大于等于远程版本号【{}】，不升级", new String[]{nowVersionInfo.getVersionUpdate(), updateInfo.getVersionUpdate()});
        }

        return mainFlag & updateFlag;
    }

    /**
     * 升级
     *
     * @author 马寅广
     * @date 2023/10/25 9:11
     **/
    public static void update() {
        // 打开升级程序
        try {
            Runtime.getRuntime().exec(UPDATE_PROGRAM);
        } catch (IOException e) {
            logger.error("启动升级程序失败：", e);
        }
    }

    /**
     * 用于程序启动时初始化版本信息
     * </br> 读取本地更新标志文件进行初始化，若没有文件，则默认 1.0.0
     *
     * @author Eugenema
     * @date 2023/11/5 16:23
     *
     *
     * @return
     **/
    public static void initVersion() {
        if (FileUtil.exist(UPDATE_FLAG_FILE)) {
            nowVersionInfo = JSON.parseObject(FileUtil.read(UPDATE_FLAG_FILE), UpdateInfo.class);
        }
    }
}
